<template>
  <view>
    <view class="im-input-wrapper">
      <!-- 发送语音的按钮，点击显示 “按住说话” 按钮 -->
      <image
        v-if="showAudio"
        :src="isVoiceMode ? keyBoard : voiceIcon"
        class="input-icon icon-audio"
        @tap="handleAudioRecord"
      />
      <!-- 文本输入 -->
      <input
        v-if="!isVoiceMode"
        type="text"
        :maxlength="-1"
        class="input-editor"
        confirm-type="send"
        auto-blur="false"
        cursor-spacing="5"
        :adjust-position="false"
        :confirm-hold="true"
        :focus="isInputFocus"
        v-model="content"
        @focus="handleInputFocus"
        @blur="handleInputBlur"
        @confirm="handleInputConfirm"
      />
      <!-- 语音录制 -->
      <view
        v-else
        class="audio-editor input-say"
        :style="isRecord ? 'background: #eee;' : 'background: #fff;'"
        @longpress="handleAudioRecordStart"
        @touchstart="touchAudioStart"
        @touchend="touchAudioEnd"
        @touchcancel="touchAudioCancel"
        @touchmove="touchAudioMove"
      >
        <text>
          <text>按住</text>
          <text style="width: 10rpx"></text>
          <text>说话</text>
        </text>
      </view>
      <!-- 功能区 -->
      <image
        v-if="showEmoji"
        :src="panelType === 'emoji' ? keyBoard : emojiIcon"
        class="input-icon icon-more"
        @click="handleEmojiClick"
      />
      <image
        :src="moreIcon"
        class="input-icon icon-more"
        @click="handleMoreClick"
      />
    </view>
    <view
      class="panel-wrapper"
      :style="{
        height: swiperWrapperHeight + 'rpx',
        transition: 'height 0.2s ease-in-out'
      }"
    >
      <!-- 下拉选项面板 -->
      <view
        class="swiper-wrapper choose-panel"
        :style="{
          height: panelType === 'choose' ? '100%' : 0,
          opacity: panelType === 'choose' ? 1 : 0,
          transition: panelType === 'choose' ? 'all 0.2s ease-in-out' : 'none'
        }"
      >
        <swiper class="swiper" :autoplay="false" :duration="300">
          <swiper-item class="choose">
            <view
              v-for="(item, itemIndex) in chooseListArrs"
              class="choose-item"
              :key="itemIndex"
              @click="handleChooseClick(item)"
            >
              <view class="choose-wrap">
                <image :src="item.icon" class="choose-icon" />
              </view>
              <view class="choose-description">{{ item.name }}</view>
            </view>
          </swiper-item>
        </swiper>
      </view>

      <!-- 表情包面板 -->
      <view
        class="swiper-wrapper emoji-panel"
        :style="{
          height: panelType === 'emoji' ? '100%' : 0,
          opacity: panelType === 'emoji' ? 1 : 0,
          transition: panelType === 'emoji' ? 'all 0.2s ease-in-out' : 'none'
        }"
      >
        <swiper
          class="showEmoji"
          :indicator-dots="false"
          :autoplay="false"
          :duration="300"
        >
          <block>
            <swiper-item>
              <view class="emoji_item">
                <image
                  v-for="(item, index) in emojiObj.map1"
                  :key="index"
                  :src="item"
                  @tap="selectEmoji"
                  :data-emoji="index"
                />
              </view>
              <view class="emoji_item">
                <image
                  v-for="(item, index) in emojiObj.map2"
                  :key="index"
                  :src="item"
                  @tap="selectEmoji"
                  :data-emoji="index"
                />
              </view>
              <view class="emoji_item">
                <image
                  v-for="(item, index) in emojiObj.map3"
                  :key="index"
                  :src="item"
                  @tap="selectEmoji"
                  :data-emoji="index"
                />
              </view>
              <view class="emoji_item">
                <image
                  v-for="(item, index) in emojiObj.map4"
                  :key="index"
                  :src="item"
                  @tap="selectEmoji"
                  :data-emoji="index"
                />
              </view>
              <view class="emoji_item">
                <image
                  v-for="(item, index) in emojiObj.map5"
                  :key="index"
                  :src="item"
                  @tap="selectEmoji"
                  :data-emoji="index"
                />
              </view>
            </swiper-item>
          </block>
        </swiper>
      </view>
    </view>
  </view>
</template>

<script>
const recorderManager = uni.getRecorderManager();
const innerAudioContext = uni.createInnerAudioContext();
innerAudioContext.autoplay = true;

export default {
  name: 'MsgInputBar',

  components: {},

  data() {
    return {
      // 图标
      moreIcon: require('./imgs/ad.png'),
      emojiIcon: require('./imgs/Emoji.png'),
      voiceIcon: require('./imgs/voice.png'),
      keyBoard: require('./imgs/keyboard.png'),

      // 文本内容
      content: '',

      // 输入框聚焦状态
      isInputFocus: false,

      // 是否录制中
      isRecord: false,
      isEnter: false,

      // 是否语音模式
      isVoiceMode: false,

      // 选项卡的高度
      swiperWrapperHeightInit: 460,

      panelType: '',

      // 录音相关
      recordNum: 0,
      recordTimer: '',
      voicePath: '',

      // 键盘占用高度
      keyboardHeight: 0,

      // 设备信息
      sysInfo: {}
    };
  },

  props: {
    theme: {
      type: String,
      default: ''
    },
    // 连接标识
    imId: {
      type: String,
      default: '',
      required: true
    },
    // 接收者
    toUser: {
      type: String,
      default: '',
      required: true
    },
    //下拉面板
    chooseList: {
      type: Array,
      default: () => []
    },
    // 表情
    emoji: {
      type: Object,
      default: () => {},
      required: true
    },
    // 表情
    emojiObj: {
      type: Object,
      default: () => {},
      required: true
    },
    // 是否启用表情
    showEmoji: {
      type: Boolean,
      default: true
    },
    // 是否启用语音
    showAudio: {
      type: Boolean,
      default: true
    }
  },

  computed: {
    swiperWrapperHeight() {
      if (
        this.keyboardHeight > 0 &&
        this.keyboardHeight > this.swiperWrapperHeightInit
      ) {
        return this.keyboardHeight;
      } else if (this.panelType) {
        return this.swiperWrapperHeightInit;
      }
      return 40;
    },
    chooseListArrs() {
      // 相册 + 拍摄 默认有
      return [
        {
          name: '相册',
          type: 'album',
          icon: require('../common/all_picture.png')
        },
        {
          name: '拍摄',
          type: 'camera',
          icon: require('../common/all_camera.png')
        }
      ].concat(this.chooseList);
    }
  },

  watch: {
    swiperWrapperHeight(newVal, olaVal) {
      if (newVal !== olaVal) {
        this.$emit('inputBarHeightChange');
      }
    }
    // isInputFocus(newVal) {
    //   if (newVal) {
    //     this.panelType = '';
    //   }
    // }
  },

  mounted() {
    // 键盘高度变化监听
    uni.onKeyboardHeightChange(res => {
      this.keyboardHeight = res.height * (750 / this.sysInfo.windowWidth);
      if (res.height > 0) {
        // 键盘启用
      } else {
        //
      }
    });

    // 为了防止苹果手机静音无法播放
    uni.setInnerAudioOption({
      obeyMuteSwitch: false
    });

    recorderManager.onStop(res => {
      this.recordTimer && clearInterval(this.recordTimer);
      if (this.recordNum < 1100) {
        uni.showToast({
          title: '录音时间不足',
          duration: 1600,
          icon: 'none'
        });
      } else if (!this.isEnter) {
        this.voicePath = res.tempFilePath;
        // 发送语音消息
        this.$hxim.get(this.imId).sendAudio({
          path: res.tempFilePath,
          to: this.toUser,
          audioLength: Math.ceil(this.recordNum / 1000),
          ext: {}
        });
      }
    });

    this.sysInfo = uni.getSystemInfoSync();
  },

  methods: {
    // 录音按钮点击
    handleAudioRecord() {
      this.isVoiceMode = !this.isVoiceMode;
      this.isInputFocus = !this.isVoiceMode;

      if (this.isVoiceMode) {
        this.panelType = '';
      }
    },

    // 开始录制
    handleAudioRecordStart() {
      this.startRecord();
    },

    // 开始录制
    startRecord() {
      // 显示浮层
      this.$emit('audioInfoUpdate', {
        showLayer: true
      });
      recorderManager.start();
      this.calcRecordTime();
    },

    endRecord() {
      // 关闭录音
      recorderManager.stop();
      // 关闭浮层
      this.$emit('audioInfoUpdate', {
        showLayer: false
      });
      this.recordTime && clearTimeout(this.recordTime);
    },

    // 计算录音时间
    calcRecordTime() {
      this.recordNum = 0;
      this.recordTimer = setInterval(() => {
        this.recordNum += 500;
      }, 500);
    },

    // 输入框聚焦
    handleInputFocus(e) {
      this.panelType = '';
      this.isInputFocus = true;
      this.$emit('inputFocus', e);
    },

    // 输入框失焦
    handleInputBlur(e) {
      this.isInputFocus = false;
      this.$emit('inputBlur', e);
    },

    // 输入框确认
    handleInputConfirm() {
      this.$emit('inputConfirm', this.content);
      if (this.content.trim()) {
        // 发送文本消息
        this.$hxim.get(this.imId).sendText({
          msg: this.content,
          chatType: 'chat',
          to: this.toUser,
          ext: {}
        });
        this.content = '';
      }
    },

    touchAudioStart() {
      this.isRecord = true;
      // uni.showToast({
      //   title: '语音功能待支持ing~',
      //   icon: 'none'
      // });
    },

    touchAudioEnd() {
      console.log('touchAudioEnd');
      this.isRecord = false;
      this.endRecord();
    },

    touchAudioCancel() {
      this.isRecord = false;
      this.endRecord();
    },

    /*
     * touchmove
     * 判断当前触点的位置和取消目标的中心坐标的距离
     * 进入区域后给予样式反馈
     * 离开区域后同样给予样式反馈
     * 如果在区域内触点离开，取消当前语音消息的发送
     */

    touchAudioMove(e) {
      const cancelLocation = getApp().globalData.recordCancelInfo;

      if (cancelLocation.circleX && cancelLocation.circleY) {
        // 简化参数
        const x1 = e.touches[0].clientX;
        const y1 = e.touches[0].clientY;
        const x2 = cancelLocation.circleX;
        const y2 = cancelLocation.circleY;
        // 开始计算位置距离
        const distance = Math.sqrt(
          Math.pow(y1 - y2, 2) + Math.pow(x1 - x2, 2)
        ).toFixed(2);

        if (Number(distance) >= Number(cancelLocation.circleRadius)) {
          // 未进入取消区域范围
          this.$emit('audioInfoUpdate', {
            enterCancel: false,
            showLayer: true
          });
          this.isEnter = false;
        } else {
          // 进入取消区域范围
          this.$emit('audioInfoUpdate', {
            enterCancel: true,
            showLayer: true
          });
          this.isEnter = true;
        }
      }
    },

    // 更多 + 点击
    handleMoreClick() {
      this.isVoiceMode = false;
      this.panelType = this.panelType === 'choose' ? '' : 'choose';
      this.isInputFocus = !this.panelType;
    },

    // 表情按钮点击
    handleEmojiClick() {
      this.isVoiceMode = false;
      this.panelType = this.panelType === 'emoji' ? '' : 'emoji';
      this.isInputFocus = !this.panelType;
    },

    // 选项卡点击
    handleChooseClick(item) {
      if (item.type === 'album') {
        this.choosePhotoOrCamera('album');
      }
      if (item.type === 'camera') {
        this.choosePhotoOrCamera('camera');
      }
      item.handler && item.handler(item);
    },

    // 设置下拉选项面板显隐
    setIsShowSwiper() {
      this.panelType = '';
    },

    // 选择 emoji,暂时只支持往后插入
    selectEmoji(event) {
      const emoji = event.target.dataset.emoji;
      // 这里要获取光标的位置
      this.content += emoji;
      // this.isInputFocus = true;
    },

    // 拍照或相册
    choosePhotoOrCamera(type = 'camera') {
      uni.chooseImage({
        count: 1,
        sourceType: [type],
        sizeType: ['compressed'],
        success: async resp => {
          // 发送图片消息
          this.$hxim.get(this.imId).sendImg({
            path: resp.tempFilePaths[0],
            to: this.toUser,
            ext: {}
          });
        }
      });
    }
  }
};
</script>

<style lang="scss" scoped>
@import '../common/index';
.im-input-wrapper {
  padding-right: 24rpx;
  width: 100%;
  min-height: 114rpx;
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
  position: relative;
  border-top: 2rpx solid #ebebeb;
  box-sizing: border-box;

  .input::before {
    content: ' ';
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 1rpx;
    background-color: #dadada;
    -webkit-transform-origin: 0 0;
    transform-origin: 0 0;
    -webkit-transform: scaleY(0.5);
    transform: scaleY(0.5);
  }

  .input::after {
    content: ' ';
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 1rpx;
    background-color: #c1c1c1;
    -webkit-transform-origin: 0 0;
    transform-origin: 0 0;
    -webkit-transform: scaleY(0.5);
    transform: scaleY(0.5);
  }

  .input-icon {
    width: 54rpx;
    height: 54rpx;
  }

  .icon-audio {
    margin-left: 22rpx;
  }

  .icon-emoji {
    margin-left: 20rpx;
  }

  .icon-more {
    margin-left: 24rpx;
  }

  .input-editor {
    box-sizing: content-box;
    // width: 438rpx;
    height: 50rpx;
    padding: 15rpx 20rpx;
    background-color: #fff;
    border-radius: 8rpx;
    margin-left: 24rpx;
    // display: flex;
    // justify-content: flex-start;
    // align-items: center;
    caret-color: #a0ea71;
    outline: none;
    overflow: hidden;
    flex: 1;
  }

  .audio-editor {
    box-sizing: content-box;
    // width: 438rpx;
    height: 50rpx;
    padding: 15rpx 20rpx;
    border-radius: 8rpx;
    margin-left: 24rpx;
    flex: 1;
  }

  .input-say {
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 30rpx;
    font-weight: bold;
  }

  #editor {
    height: auto;
    margin: 15rpx 0;
    overflow-y: scroll;
  }
}

.panel-wrapper {
  position: relative;
}

.swiper-wrapper {
  position: absolute;
  width: 100%;
  bottom: 0;
}

.swiper-wrapper.choose-panel {
  width: 100%;
  background: #f6f6f6;

  .swiper {
    height: 100%;
    padding: 30rpx 20rpx 0;
    box-sizing: border-box;
  }

  .choose {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: flex-start;
    height: auto !important;
  }

  .choose-item {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    width: 25%;
    background-color: transparent;
    text-align: center;
  }

  .choose-wrap {
    width: 130rpx;
    height: 130rpx;
    background-color: #fff;
    text-align: center;
    border-radius: 25rpx;
    display: flex;
    align-items: center;
    justify-content: center;
  }

  .choose-icon {
    width: 50rpx;
    height: 50rpx;
  }

  .choose-description {
    font-size: 26rpx;
    color: #000;
    margin: 20rpx 0 30rpx;
  }
}

.swiper-wrapper.emoji-panel {
  width: 100%;
  background: #f6f6f6;

  .emoji_list {
    margin-top: 60rpx;
    width: 100%;
    height: 290rpx;
    background-color: #dddddd;
    padding-top: 20rpx;
    padding-left: 3%;
    display: none;
  }

  .showEmoji {
    width: 100%;
    height: 100%;
    padding-top: 20rpx;
    padding-left: 3%;
    display: block;
  }

  .emoji_list image,
  .showEmoji image {
    width: 60rpx;
    height: 60rpx;
    margin: 10rpx 2%;
  }

  .emoji {
    width: 52rpx;
    height: 52rpx;
    margin: 0 0;
  }

  .emoji_item {
    display: flex;
    justify-content: space-around;
    margin-right: 40rpx;
  }
  .last_item {
    justify-content: flex-end !important;
  }
}
</style>
